`timescale 1ns / 1ps

`include "bmp_gen_lib.v"
`include "vga_param.v"

module bmp_gen(
    //Inputs
     input clk_vga
    ,input rst_n
    ,input vga_hsync
    ,input vga_vsync
    ,input [15:0] vga_data
);
    
    bmp_gen_lib bmp_gen_lib_ut0();

    reg [13:0] cnt_h = 0, cnt_v = 0;
    reg [13:0] bmp_num = 0;
    
    wire h_valid = (cnt_h >= `VGA_HB) & (cnt_h < (`VGA_HB + `VGA_HC));
    wire v_valid = (cnt_v > `VGA_VP) & (cnt_v <= (`VGA_VP + `VGA_VQ));
    wire rgb_valid = h_valid & v_valid;

    wire [31:0] bmp_width  = `VGA_WIDTH;
    wire [31:0] bmp_height = `VGA_HEIGHT;
    reg [31:0] bmp_width_align;

    integer fd = 0;
    integer i = 0, j = 0, idx_h = 0, idx_w = 0;

    always @ (posedge clk_vga) begin
        if(!rst_n) 
            cnt_h <= 0;
        else if(!vga_hsync) 
            cnt_h <= 0;
        else if(vga_hsync & (cnt_h != `VGA_HE - `VGA_HA))
            cnt_h <= cnt_h + 1;
        
        if(!rst_n)
            cnt_v <= 0;
        else if(!vga_vsync)
            cnt_v <= 0;
        else if(vga_vsync & (cnt_h == `VGA_HE - `VGA_HA)) begin
            if(cnt_v != `VGA_VS - `VGA_VO)
                cnt_v <= cnt_v + 1;
        end
    end
    
    //Create file on vga_vsync rising edge
    always @ (posedge vga_vsync) begin
        if(rst_n) 
            bmp_gen_lib_ut0.bmp_new(bmp_num, bmp_width, bmp_height, bmp_width_align, fd);
    end
    
    //Close file at vga_vsync falling edge
    always @ (negedge vga_vsync) begin
        if(rst_n) begin
            $fseek(fd,  0, 2);  //to EOF, offset = 0
            bmp_gen_lib_ut0.bmp_write_zero(fd, 2);
            bmp_gen_lib_ut0.bmp_close(fd, bmp_num);
            bmp_num = bmp_num + 1;
        end
    end
    
    //fseek file at rising rgb_valid
    always @ (posedge rgb_valid) begin
        if(idx_h < bmp_height)
            idx_h = idx_h + 1;
        else 
            idx_h = 1;
        $fseek(fd, 54 + bmp_width_align*(bmp_height - idx_h), 0); 
        // $display("%t: fseek %d", $time, 54 + bmp_width_align*(bmp_height - idx_h));
    end
    
    always @ (posedge clk_vga) begin
        if(!rst_n)
            idx_w = 0;
        else if(rgb_valid) begin
            if(idx_w == bmp_width_align)
                idx_w = 0;
            else 
                idx_w = idx_w + 1;
        end
        else 
            idx_w = 0;
    end

    always @ (posedge clk_vga) begin
        if(rgb_valid) begin
            // $display("w:%4d, h:%d, %4x", idx_w, idx_h, vga_data[15:0]);
            bmp_gen_lib_ut0.bmp_write(fd, vga_data[15:0]);
            if(idx_w == bmp_width)
                bmp_gen_lib_ut0.bmp_write_zero(fd, bmp_width_align - bmp_width*3);  //write zero
        end
    end
    
endmodule

